/**
 * 简单封装一下WS消息
 */
import ReconnectingWebSocket from '@/utils/websocket/reconnecting-websocket'

const WS_CONNECT_INFO_KEY = 'ws_connect_info'

/**
 * 绑定消息到对象
 * @param {*} id
 * @param {*} instance
 */
export function bindSocketMessage(id, instance) {
  unbindSocketMessage(id)
  messageInstances.push({
    id,
    instance,
  })
}

/**
 * 取消指定id的事件绑定
 * @param {*} id
 */
export function unbindSocketMessage(id) {
  console.log(`unbind socket message '${id}'.`)
  const idx = messageInstances.findIndex((d) => {
    return d.id === id
  })
  if (idx >= 0) {
    messageInstances.splice(idx, 1);
  }
}

/**
 * 判断是否已连接
 */
export function isConnected() {
  return webSocketInstance && webSocketInstance.readyState === WebSocket.OPEN
}

/**
 * 重新连接
 */
export function reconnect() {
  webSocketInstance && webSocketInstance.refresh()
}

const messageInstances = []
let connectCounter = 0
let webSocketInstance = null
let onConnectedHandler = null

const socketMessageHandlers = {
  async connectSuccess(data) {
    sessionStorage.setItem('connectionId', data.connectionId)
    connectCounter++
    onConnectedHandler && onConnectedHandler(data.connectionId)
    console.log('坐席平台服务连接成功！')
  },
  async updateData(data) {},
}

/**
 * 获取重连次数，大于1代表已重连过至少一次
 */
export function getWebsocketConnectCounter() {
  return connectCounter
}

let _getReconnectingParams = () => {
  return {}
}

export function setGetReconnectingParamsHandler(handler) {
  _getReconnectingParams = handler
}

/**
 * 初始化Websocket连接，闭包相关内部业务函数
 */
export default function initWebsocket(onConnected) {
  if (!webSocketInstance) {
    webSocketInstance = new ReconnectingWebSocket(
      'ws://127.0.0.1:8091/',
      null,
      {
        debug: true,
        reconnectInterval: 3000,
      }
    )
  }
  onConnectedHandler = onConnected
  const ws = webSocketInstance
  async function callMethod(methodName, data) {
    const defaultMethod = socketMessageHandlers[methodName]
    if (defaultMethod && defaultMethod.IsFunction) {
      const methodRes = await defaultMethod(data)
      if (methodRes === false) {
        return
      }
    }

    // 回调绑定消息实例的方法
    if (messageInstances.length) {
      messageInstances.forEach((d) => {
        const instance = d.instance
        const instanceMethod = instance[methodName]
        if (instanceMethod && instanceMethod.IsFunction) {
          instanceMethod.call(instance, data)
        }
      })
    }
  }

  ws.onopen = async () => {
    console.log('ws connected')
    function connect() {
      let _params = {}
      try {
        _params = _getReconnectingParams()
      } catch (err) {}
      const data = {
        method: 'connect',
        params: {
          ..._params,
        },
      }
      // 发送连接请求
      ws.send(JSON.stringify(data))
    }

    // 验证token是否有效
    try {
      connect()
    } catch (err) {
      console.error(`${err.message}，连接失败！`)
    }
  }

  ws.onclose = () => {
    console.warn('ws closed')
    callMethod('connectClosed', { ws })
  }

  ws.onconnecting = () => {
    console.log('正在连接坐席平台消息服务...')
  }

  ws.onmessage = async (evt) => {
    // 每次收到消息，就重新开始准备发送心跳包，默认间隔4分钟一次
    const msg = evt.data
    if (msg) {
      console.log(msg)
      const res = JSON.parse(msg)
      if (res.meta) {
        if (res.meta.code === 0) {
          // 正常返回
          const methodName = res.data.method
          if (methodName) {
            const data = res.data.data
            await callMethod(methodName, data)
          }
        } else {
          // 发生异常
          console.error(res.meta.message)
        }
      }
    }
  }
  return ws
}

/**
 * 向服务端订阅数据消息
 * @param {*} param0 
 * @returns 
 */
export function subscribe({ name, id }) {
  if (webSocketInstance && webSocketInstance.readyState === 1) {
    const connectionId = sessionStorage.getItem('connectionId')
    if (!connectionId) {
      console.error('connectionId的值无效！')
      return
    }
    webSocketInstance.send(
      JSON.stringify({
        method: 'subscribe',
        data: { name, id, connectionId },
      })
    )
  }
}
